import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class CellularPhone extends Thread {

    private volatile boolean callInProgress = false;
    private volatile boolean keepGoing = true;
    private final Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    private List<String> list = new CopyOnWriteArrayList<>();

    public CellularPhone(String name) {
        super(name);
    }

    /**
     * 假设控制台是手机的窗口。
     *
     * @param message 要显示的消息
     */
    void display(String message) {
        System.out.println(message);
    }

    /**
     * 接听电话。在终端显示消息。
     *
     * @param name               调用方的名称
     * @param callDisplayMessage 呼叫正在进行时显示的消息
     */
    public void startCall(String name, String callDisplayMessage) {
        callInProgress = true;
        display("<" + name + ">: Call (" + callDisplayMessage + ") begins");
    }

    /**
     * 挂断电话。在此方法完成后，电话能够接听其他电话。
     *
     * @param name               调用方的名称
     * @param callDisplayMessage 要显示的消息
     */
    public void endCall(String name, String callDisplayMessage) {
        display("   <" + name + ">: Call (" + callDisplayMessage + ") ends");
        callInProgress = false;
    }

    /**
     * 显示手机正在等待做某事
     */
    private void displayWaiting() {
        display("<" + this.getName() + ">: Waiting...");
    }

    /**
     * 停止电话接听程序
     */
    public void stopPhone() {
        keepGoing = false;
    }

    /**
     * 将消息输出到控制台
     *
     * @param newMessage
     */
    public void addMessage(String newMessage) {
        list.add(newMessage);
    }

    private void displayMessages() {
        lock.lock();
        for (String s : list) {
            display("<" + getName() + ">:Massage:" + s);
        }
        list.clear();
        lock.unlock();
    }

    public Lock getLock() {
        return lock;
    }

    public Condition getCondition() {
        return condition;
    }

    /**
     * 运行模拟器
     */
    public void run() {
        // 循环直到stopPhone被调用
        while (keepGoing) {
            // 如果没有电话
            if (!callInProgress) {
                if(!list.isEmpty()) {
                    displayMessages();           //没电话输出信息
                }
                displayWaiting();
                // 假装手机在做别的事情
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
